package com.kylin.common.core.validator.constraint;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 字段重复校验实现
 *
 * @author wuhao
 * @version 1.0 - 2020/9/2
 */
@Slf4j
public class NotRepeatValidatorClass implements ConstraintValidator<NotRepeat, Object> {

    private String id;
    private String field;
    private String message;


    @Override
    public void initialize(NotRepeat fieldRepeatValidator) {
        this.id = fieldRepeatValidator.id();
        this.field = fieldRepeatValidator.field();
        this.message = fieldRepeatValidator.message();
    }

    @SneakyThrows
    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {

        // 校验字段的值
        Object fieldValue = "";
        // 校验字段对应的数据库字段名
        String fieldDbName = "";
        // 主键的值
        String idKey = "";
        Object idValue = "";

        // 工厂模式 + ar动态语法
        TableInfo tableInfo = TableInfoHelper.getTableInfo(o.getClass());
        // 利用反射获取属性值
        List<Field> allFields = TableInfoHelper.getAllFields(o.getClass());
        for(Field item : allFields) {
            // 设置对象中成员 属性private为可读
            item.setAccessible(true);
            // 获取fieldValue
            if(item.getName().equals(field)) {
                fieldValue = item.get(o);
            }
            // 获取主键值
            if(item.getName().equals(tableInfo.getKeyProperty())) {
                idValue = item.get(o);
            }
        }

        idKey = tableInfo.getKeyColumn();
        List<TableFieldInfo> fieldList = tableInfo.getFieldList().stream()
                .filter(i -> i.getProperty().equals(field)).collect(Collectors.toList());
        if(fieldList != null && fieldList.size() != 1) {
            log.warn(String.format("重名校验字段【%s】不存在，请认真检查代码！", field));
            return true;
        }
        // 获取校验字段
        fieldDbName = fieldList.get(0).getColumn();
        // 组装检测sql
        Model entity = (Model) o;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(fieldDbName, fieldValue);
        queryWrapper.ne(!Objects.isNull(idValue), idKey, idValue);
        List list = entity.selectList(queryWrapper);
        if(list != null && list.size() > 0 ){
            return false;
        }

        return true;
    }


}
